#ifndef PSI_H
#define PSI_H

#include <vector>
#include <string>

#include "../Input/PicParams.h"
#include "../Parallel/ParallelMPI.h"
#include "../Species/Species.h"
#include "../Diagnostic/Diagnostic.h"
#include "../Grid/Grid.h"
#include "../Tool/Log.h"

class Diagnostic;

using namespace std;
class PSI
{

public:

    PSI(PicParams* params_, ParallelMPI* pmpi_, vector<Species*>* vecSpecies_, PSIParameter psi_param_, int psi_number_):
        params(params_),
        pmpi(pmpi_),
        vecSpecies(vecSpecies_),
        psi_param(psi_param_),
        psi_number(psi_number_)
    {

    };

    virtual ~PSI(){};

    void setRelPsi(PSI* relevantPsi)
    {
        //relPsi = relevantPsi;
    }

    virtual void perform_psi(int itime){};

    //emit particles
    void emit(){};

    //calculate angle between two 3D vectors, unit is degree
    double angle_2vectors(double v1[], double v2[])
    {
        double mag1 = sqrt(pow(v1[0], 2) + pow(v1[1], 2) + pow(v1[2], 2));
        double mag2 = sqrt(pow(v2[0], 2) + pow(v2[1], 2) + pow(v2[2], 2));
        double dot_product = v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
        if(mag1 * mag2 == 0.0)
        {
            log_error<<"angle_2vectors equal to zero!";
        }
        double angle = acos(abs(dot_product) / (mag1 * mag2));
        return 180.0 * angle / params->const_pi;
    };

    PicParams* params;
    vector<Species*>* vecSpecies;
    ParallelMPI* pmpi;

    PSIParameter psi_param;

    int psi_number;







private:

};

#endif
